package ocean.chinacraft.data.recipes;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import ocean.chinacraft.common.ModBlocks;
import ocean.chinacraft.data.IJadeWorkbenchRecipe;
import ocean.chinacraft.data.ModRecipeTypes;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.item.crafting.ShapedRecipe;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.registries.ForgeRegistryEntry;

import javax.annotation.Nullable;

/**
 * 玉石工作台合成器配方
 *
 * @author zhang
 * @since 021/11/20
 */
public class JadeWorkbenchRecipe implements IJadeWorkbenchRecipe {

    private final ResourceLocation resourceLocation;
    private final ItemStack output;
    private final NonNullList<Ingredient> recipeItems;

    public JadeWorkbenchRecipe(ResourceLocation resourceLocation, ItemStack output, NonNullList<Ingredient> recipeItems) {
        this.resourceLocation = resourceLocation;
        this.output = output;
        this.recipeItems = recipeItems;
    }

    @Override
    public boolean matches(IInventory inventory, World world) {
        if (recipeItems.get(0).test(inventory.getItem(0))) {
            return recipeItems.get(1).test(inventory.getItem(1));
        }
        return false;
    }

    @Override
    public ItemStack assemble(IInventory inventory) {
        return output;
    }

    @Override
    public boolean canCraftInDimensions(int width, int height) {
        return false;
    }

    @Override
    public ItemStack getToastSymbol() {
        return new ItemStack(ModBlocks.JADE_WORKBENCH_BLOCK.get());
    }

    @Override
    public ItemStack getResultItem() {
        return output.copy();
    }

    @Override
    public ResourceLocation getId() {
        return resourceLocation;
    }

    @Override
    public IRecipeSerializer<?> getSerializer() {
        return ModRecipeTypes.JADE_WORKBENCH_TYPE.get();
    }

    public static class JadeWorkbenchRecipeType implements IRecipeType<JadeWorkbenchRecipe> {
        @Override
        public String toString() {
            return JadeWorkbenchRecipe.TYPE_ID.toString();
        }
    }

    public static class Serializer extends ForgeRegistryEntry<IRecipeSerializer<?>>
            implements IRecipeSerializer<JadeWorkbenchRecipe> {

        @Override
        public JadeWorkbenchRecipe fromJson(ResourceLocation resourceLocation, JsonObject json) {
            ItemStack output = ShapedRecipe.itemFromJson(JSONUtils.getAsJsonObject(json, "output"));
            JsonArray ingredients = JSONUtils.getAsJsonArray(json, "ingredients");
            NonNullList<Ingredient> inputs = NonNullList.withSize(2, Ingredient.EMPTY);
            for (int i = 0; i < inputs.size(); i++) {
                inputs.set(i, Ingredient.fromJson(ingredients.get(i)));
            }
            return new JadeWorkbenchRecipe(resourceLocation, output, inputs);
        }

        @Nullable
        @Override
        public JadeWorkbenchRecipe fromNetwork(ResourceLocation resourceLocation, PacketBuffer buffer) {
            NonNullList<Ingredient> inputs = NonNullList.withSize(buffer.readInt(), Ingredient.EMPTY);
            for (int i = 0; i < inputs.size(); i++) {
                inputs.set(i, Ingredient.fromNetwork(buffer));
            }
            ItemStack output = buffer.readItem();
            return new JadeWorkbenchRecipe(resourceLocation, output, inputs);
        }

        @Override
        public void toNetwork(PacketBuffer buffer, JadeWorkbenchRecipe recipe) {
            buffer.writeInt(recipe.getIngredients().size());
            for (Ingredient ing : recipe.getIngredients()) {
                ing.toNetwork(buffer);
            }
            buffer.writeItemStack(recipe.getResultItem(), false);
        }
    }
}
